/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package instantmessengercpsc360.client;

import java.awt.event.KeyEvent;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;

/**
 *
 * @author nicholas
 */
public class ClientMainFrame extends javax.swing.JFrame implements ClientListUpdateEventListener, 
                                                                   UsernameUpdateEventListener,
                                                                   MsgEventListener,
                                                                   ConvListUpdateEventListener
{
    /**
     * Creates new form ClientMainFrame
     */
    public ClientMainFrame() {
        initComponents();
    }
    
    ServerLiaison sv;
    
    public void startConnecting() throws IOException
    {
        ClientConnectDialog cd = new ClientConnectDialog(this, true);
        cd.setVisible(true);
        if (cd.getResult())
        {
            serverAddress = cd.getIp();
            port = cd.getPort();
            username = cd.getUsername();
            cd.dispose();
            connect();
        }
    }
    
    public void connect() throws IOException
    {
        this.setTitle(username + "@" + serverAddress + ":" + port);
        sl = new ServerLiaison(this, serverAddress, port);
        sl.addUsernameUpdateEventListener(this);
        sl.addClientListUpdateEventListener(this);
        new Thread(sl).start();
    }
    
    public void connect(String[] args) throws IOException
    {
        try {
            username = args[0];
            serverAddress = InetAddress.getByName(args[1]);
            port = Integer.parseInt(args[2]);
            connect();
        } catch (NumberFormatException ex) {

        } catch (UnknownHostException ex) {

        }
        
    }
    
    InetAddress serverAddress;
    Integer port;
    static String username;
    ServerLiaison sl;
    DefaultListModel onlineListModel = new DefaultListModel();
    DefaultListModel convListModel = new DefaultListModel();
    String conversation = "";
    ArrayList<String> members = new ArrayList<String>();
    
    //String msg;

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        scrListUsers = new javax.swing.JScrollPane();
        listUsers = new javax.swing.JList(onlineListModel);
        lblUsers = new javax.swing.JLabel();
        lblCurConversation = new javax.swing.JLabel();
        scrEtxtUserInput = new javax.swing.JScrollPane();
        etxtUserInput = new javax.swing.JEditorPane();
        lblStatus = new javax.swing.JLabel();
        btnConnect = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        listConv = new javax.swing.JList(convListModel);
        jLabel1 = new javax.swing.JLabel();
        btnSend = new javax.swing.JButton();
        jScrollPane3 = new javax.swing.JScrollPane();
        txtMsgPane = new javax.swing.JTextPane();
        jButton1 = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        menuCxns = new javax.swing.JMenu();
        btnMenuConnect = new javax.swing.JMenuItem();
        btnMenuRefresh = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Instant Messaging Client");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });
        getContentPane().setLayout(new java.awt.GridBagLayout());

        scrListUsers.setViewportView(listUsers);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.ipadx = 77;
        gridBagConstraints.ipady = 401;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(6, 12, 0, 12);
        getContentPane().add(scrListUsers, gridBagConstraints);

        lblUsers.setText("Users Online");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0);
        getContentPane().add(lblUsers, gridBagConstraints);

        lblCurConversation.setText("Current Conversation");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0);
        getContentPane().add(lblCurConversation, gridBagConstraints);

        scrEtxtUserInput.setHorizontalScrollBar(null);

        etxtUserInput.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                etxtUserInputKeyReleased(evt);
            }
        });
        scrEtxtUserInput.setViewportView(etxtUserInput);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.ipadx = 400;
        gridBagConstraints.ipady = 100;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 12, 0);
        getContentPane().add(scrEtxtUserInput, gridBagConstraints);

        lblStatus.setText("Message to send");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0);
        getContentPane().add(lblStatus, gridBagConstraints);

        btnConnect.setText("Connect");
        btnConnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnConnectActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 10, 5);
        getContentPane().add(btnConnect, gridBagConstraints);

        jScrollPane1.setViewportView(listConv);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 12, 12, 12);
        getContentPane().add(jScrollPane1, gridBagConstraints);

        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        jLabel1.setText("Conversation Members");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.insets = new java.awt.Insets(5, 12, 0, 12);
        getContentPane().add(jLabel1, gridBagConstraints);

        btnSend.setText("Send");
        btnSend.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSendActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 12, 10, 0);
        getContentPane().add(btnSend, gridBagConstraints);

        txtMsgPane.setContentType("text/html");
        txtMsgPane.setEditable(false);
        jScrollPane3.setViewportView(txtMsgPane);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(7, 12, 0, 0);
        getContentPane().add(jScrollPane3, gridBagConstraints);

        jButton1.setText("Disconnect");
        jButton1.setMinimumSize(new java.awt.Dimension(150, 29));
        jButton1.setPreferredSize(new java.awt.Dimension(100, 29));
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 10, 10);
        getContentPane().add(jButton1, gridBagConstraints);

        menuCxns.setText("Connections");

        btnMenuConnect.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F, java.awt.event.InputEvent.CTRL_MASK));
        btnMenuConnect.setText("Connect to Server");
        menuCxns.add(btnMenuConnect);

        btnMenuRefresh.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.event.InputEvent.CTRL_MASK));
        btnMenuRefresh.setText("Refresh User List");
        menuCxns.add(btnMenuRefresh);

        jMenuBar1.add(menuCxns);

        setJMenuBar(jMenuBar1);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        if (sl != null)
            sl.terminate();
        setVisible(false);
        this.dispose();
    }//GEN-LAST:event_formWindowClosing

    private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConnectActionPerformed
        if (!sl.isConnected() && !sl.isConnecting())
        {
            try {
                startConnecting();
            } catch (IOException ex) {
                Logger.getLogger(ClientMainFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        else if (listUsers.getSelectedIndex() != -1)
        {
            sl.connect((String)listUsers.getSelectedValue());
        }
    }//GEN-LAST:event_btnConnectActionPerformed

    private void btnSendActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSendActionPerformed
        sl.writeMessage(etxtUserInput.getText());
        etxtUserInput.setText("");
    }//GEN-LAST:event_btnSendActionPerformed

    private void etxtUserInputKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_etxtUserInputKeyReleased
        if (evt.getKeyCode() == KeyEvent.VK_ENTER)
        {
            sl.writeMessage(etxtUserInput.getText());
            etxtUserInput.setText("");
        }
    }//GEN-LAST:event_etxtUserInputKeyReleased

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        if (sl.isConnected())
            sl.disconnect();
    }//GEN-LAST:event_jButton1ActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ClientMainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ClientMainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ClientMainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ClientMainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        
        if (args.length == 3)
        {
            final String[] inputs = args;
            java.awt.EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    ClientMainFrame cl = new ClientMainFrame();
                    cl.setVisible(true);
                    try {
                        cl.connect(inputs);
                    } catch (IOException ex) {
                        Logger.getLogger(ClientMainFrame.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
        }
        else
        {
            /*
            * Create and display the form
            */
            java.awt.EventQueue.invokeLater(new Runnable() {

                @Override
                public void run() {
                    ClientMainFrame cl = new ClientMainFrame();
                    cl.setVisible(true);

                    Boolean connected = false;
                    while (!connected)
                    {
                        try
                        {
                            cl.startConnecting();
                            connected = true;
                        }
                        catch (IOException ex) {
                            System.err.println(ex.getMessage());
                        }
                    }
                }
            });
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnConnect;
    private javax.swing.JMenuItem btnMenuConnect;
    private javax.swing.JMenuItem btnMenuRefresh;
    private javax.swing.JButton btnSend;
    private javax.swing.JEditorPane etxtUserInput;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JLabel lblCurConversation;
    private javax.swing.JLabel lblStatus;
    private javax.swing.JLabel lblUsers;
    private javax.swing.JList listConv;
    private javax.swing.JList listUsers;
    private javax.swing.JMenu menuCxns;
    private javax.swing.JScrollPane scrEtxtUserInput;
    private javax.swing.JScrollPane scrListUsers;
    private javax.swing.JTextPane txtMsgPane;
    // End of variables declaration//GEN-END:variables

    /**
     * @param evt 
     */
    @Override
    public void ClientListUpdateEventOccurred(ClientListUpdateEvent evt) {
        if (evt.getType() == ClientListUpdateEvent.ADD_LIST)
        {
            for (String s : evt.getAdds())
                onlineListModel.addElement(s);
        }
        else if (evt.getType() == ClientListUpdateEvent.ADD)
            onlineListModel.addElement(evt.getAddClient());
        else if (evt.getType() == ClientListUpdateEvent.DEL)
            onlineListModel.removeElement(evt.getDelClient());
        listUsers.repaint();
    }

    @Override
    public void UsernameUpdateEventOccurred(UsernameUpdateEvent evt) {
        username = (String)evt.getSource();
        this.setTitle(username + "@" + serverAddress + ":" + port);
    }

    @Override
    public void MsgEventOccurred(MsgEvent evt) {
        String msg = (String)evt.getSource();
        String color = evt.getColor();
        conversation += "<font color=\""+color+"\">" + msg + "</font><br/>";
        String current =  conversation;
        txtMsgPane.setText(current);
    }
    
    @Override
    public void ConvListUpdateEventOccurred(ConvListUpdateEvent evt) {
        convListModel.clear();
        for (String s : evt.getMembers())
            convListModel.addElement(s);
    }
    
}
